package com.om.common;

import Utils.HttpClientUtils;
import org.apache.http.HttpEntity;
import org.apache.http.HttpHeaders;
import org.apache.http.client.methods.CloseableHttpResponse;
import org.apache.http.client.methods.HttpGet;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.client.methods.HttpPut;
import org.apache.http.client.utils.URIBuilder;
import org.apache.http.entity.ContentType;
import org.apache.http.entity.StringEntity;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.util.EntityUtils;
import org.apache.spark.api.java.JavaRDD;
import org.codehaus.jackson.map.ObjectMapper;

import java.io.IOException;
import java.io.Serializable;
import java.net.URI;
import java.net.URISyntaxException;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.HashMap;
import java.util.regex.Pattern;

/**
 * @author zhxia
 * @date 2020/11/3 12:55
 */
public class CommonObject extends CommonProperties implements CommMethod, Serializable {
    public static ObjectMapper objectMapper = new ObjectMapper();
    static HashMap noregionvaluemap=new HashMap();
    static {
        noregionvaluemap.put("continent_name",null);
        noregionvaluemap.put("region_iso_code",null);
        noregionvaluemap.put("city_name",null);
        noregionvaluemap.put("country_iso_code",null);
        HashMap<Object, Object> objectObjectHashMap = new HashMap<>();
        objectObjectHashMap.put("lon",null);
        objectObjectHashMap.put("lat",null);
        noregionvaluemap.put("location",objectObjectHashMap);
    }

    public static boolean ismatch(String s) {
        if (!s.contains(".")) return false;
        int lastindex = s.lastIndexOf(".");
        String endwith = s.substring(lastindex);
        if(CommonProperties.filterdata.contains(endwith)){
            return true;
        }

        return false;
    }

    @Deprecated
    @Override
    public HashMap assemblydata(Object jsonData, String id) throws KeyManagementException, NoSuchAlgorithmException, IOException {
        return null;
    }

    @Override
    public HashMap assemblydataNew(CloseableHttpClient client, Object jsonData, String id) throws KeyManagementException, NoSuchAlgorithmException, IOException {
        return null;
    }
    @Override
    public HashMap getLocationByIPNew(CloseableHttpClient client, String ip, String index, String id) throws NoSuchAlgorithmException, KeyManagementException {
        if(!ip.startsWith("100")){
            String payload = "{\n\t\"ip\": \"%s\"\n}";
            String formatpayload = String.format(payload, ip);
//            CloseableHttpClient client = HttpClientUtils.getClient();
            CloseableHttpResponse iptoRegionInfo = null;
            CloseableHttpResponse putRegionInfo=null;
            try {
                //结局根据ip解析地域慢问题
                //查询是否有对应的ip地域信息。
                long getregioninfostart = System.currentTimeMillis();
                iptoRegionInfo = getIptoRegionInfo(client, auth, ip);
                long getregioninfoend = System.currentTimeMillis();
                System.out.println("query ipregioninfo exiest spend: "+(getregioninfoend-getregioninfostart)+ " milliseconds");
                if(iptoRegionInfo.getStatusLine().getStatusCode()!=200&&iptoRegionInfo.getStatusLine().getStatusCode()!=201){
                    //保存ip对应的地域信息。
                    iptoRegionInfo.close();
                    long putIpForRegionInfostart = System.currentTimeMillis();
                    URI puturi = new URIBuilder().setScheme(SCHEME).setHost(HOST).setPort(Integer.parseInt(PORT)).setPath("/" + ip_to_region + "/_doc/" + ip).setParameter("pipeline", "geoip").build();
                    HttpPut httpPut = new HttpPut(puturi);
                    httpPut.setEntity(new StringEntity(formatpayload, "UTF-8"));
                    httpPut.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
                    httpPut.addHeader("Authorization", auth);
                    putRegionInfo= client.execute(httpPut);
                    //关闭，防止下边
                    putRegionInfo.close();
                    //再次获取地域信息
                    iptoRegionInfo = getIptoRegionInfo(client, auth, ip);
                    System.out.println("putIpForRegionInfo spend: "+(System.currentTimeMillis()-putIpForRegionInfostart)+ " milliseconds");
                }
                //组装返回数据
                HttpEntity entity = iptoRegionInfo.getEntity();
                String data = EntityUtils.toString(entity);
                //数据格式{"_index":"ip_to_region","_type":"_doc","_id":"220.235.230.220","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"geoip":{"continent_name":"Oceania","region_iso_code":"AU-NT","city_name":"Parap","country_iso_code":"AU","region_name":"Northern Territory","location":{"lon":130.8414,"lat":-12.4305}},"ip":"220.235.230.220"}}
                HashMap jsonNode = objectMapper.readValue(data, HashMap.class);
                Object o = ((HashMap) jsonNode.get("_source")).get("geoip");
                return o==null?noregionvaluemap:(HashMap) o;
            } catch (IOException | URISyntaxException e) {
                return new HashMap();
            } finally {
                if (iptoRegionInfo != null) {
                    try {
                        iptoRegionInfo.close();
                    } catch (IOException ignored) {
                    }
                }
            }
        }else {
            return noregionvaluemap;
        }
    }

    @Deprecated
    @Override
    public HashMap getLocationByIP(String ip, String index, String id) throws NoSuchAlgorithmException, KeyManagementException {
        if(!ip.startsWith("100")){
            String payload = "{\n\t\"ip\": \"%s\"\n}";
            String formatpayload = String.format(payload, ip);
            CloseableHttpClient client = HttpClientUtils.getClient();
            CloseableHttpResponse iptoRegionInfo = null;
            CloseableHttpResponse putRegionInfo=null;
            try {
                //结局根据ip解析地域慢问题
                //查询是否有对应的ip地域信息。
                long getregioninfostart = System.currentTimeMillis();
                iptoRegionInfo = getIptoRegionInfo(client, auth, ip);
                long getregioninfoend = System.currentTimeMillis();
                System.out.println("query ipregioninfo exiest spend: "+(getregioninfoend-getregioninfostart)+ " milliseconds");
                if(iptoRegionInfo.getStatusLine().getStatusCode()!=200&&iptoRegionInfo.getStatusLine().getStatusCode()!=201){
                    //保存ip对应的地域信息。
                    iptoRegionInfo.close();
                    long putIpForRegionInfostart = System.currentTimeMillis();
                    URI puturi = new URIBuilder().setScheme(SCHEME).setHost(HOST).setPort(Integer.parseInt(PORT)).setPath("/" + ip_to_region + "/_doc/" + ip).setParameter("pipeline", "geoip").build();
                    HttpPut httpPut = new HttpPut(puturi);
                    httpPut.setEntity(new StringEntity(formatpayload, "UTF-8"));
                    httpPut.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
                    httpPut.addHeader("Authorization", auth);
                    putRegionInfo= client.execute(httpPut);
                    //关闭，防止下边
                    putRegionInfo.close();
                    //再次获取地域信息
                    iptoRegionInfo = getIptoRegionInfo(client, auth, ip);
                    System.out.println("putIpForRegionInfo spend: "+(System.currentTimeMillis()-putIpForRegionInfostart)+ " milliseconds");
                }
                //组装返回数据
                HttpEntity entity = iptoRegionInfo.getEntity();
                String data = EntityUtils.toString(entity);
                //数据格式{"_index":"ip_to_region","_type":"_doc","_id":"220.235.230.220","_version":1,"_seq_no":0,"_primary_term":1,"found":true,"_source":{"geoip":{"continent_name":"Oceania","region_iso_code":"AU-NT","city_name":"Parap","country_iso_code":"AU","region_name":"Northern Territory","location":{"lon":130.8414,"lat":-12.4305}},"ip":"220.235.230.220"}}
                HashMap jsonNode = objectMapper.readValue(data, HashMap.class);
                Object o = ((HashMap) jsonNode.get("_source")).get("geoip");
                return o==null?noregionvaluemap:(HashMap) o;
            } catch (IOException | URISyntaxException e) {
                return new HashMap();
            } finally {
                if (iptoRegionInfo != null) {
                    try {
                        iptoRegionInfo.close();
                    } catch (IOException ignored) {

                    }
                }
            }
        }else {
            return noregionvaluemap;
        }
    }

    @Override
    public JavaRDD dealData(JavaRDD javaRDD,String[] vhosts) {
        return null;
    }

    @Override
    public String[] parseUserAgent(String userAgent) {
        return new String[3];
    }

    public  CloseableHttpResponse getIptoRegionInfo(CloseableHttpClient client, String auth, String identfy) throws IOException, URISyntaxException {
        URI geturi = new URIBuilder().setScheme(SCHEME).setHost(HOST).setPort(Integer.parseInt(PORT)).setPath("/"+ip_to_region + "/_doc/" + identfy).build();
        HttpGet httpGet = new HttpGet(geturi);
        httpGet.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
        httpGet.addHeader("Authorization", auth);
        CloseableHttpResponse getDataResponse = client.execute(httpGet);
        return getDataResponse;
    }

    public  int sendData(String data) throws NoSuchAlgorithmException, KeyManagementException {
        long start = System.currentTimeMillis();
        CloseableHttpClient httpClient = HttpClientUtils.getClient();
        System.out.println("获取连接:"+(System.currentTimeMillis()-start));
        CloseableHttpResponse execute = null;
        try {
            System.out.println(uri);
            HttpPost httpPost = new HttpPost(uri);
            httpPost.setEntity(new StringEntity(data, "UTF-8"));
            httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
            httpPost.addHeader("Authorization", auth);
            execute = httpClient.execute(httpPost);
            return execute.getStatusLine().getStatusCode();
        } catch (IOException e) {
            return execute != null ? execute.getStatusLine().getStatusCode() : 0;
        } finally {
            if (execute != null) {
                try {
                    execute.close();
                } catch (IOException ignored) {
                }
            }
        }
    }

    public  int sendData1(CloseableHttpClient httpClient, String data) throws NoSuchAlgorithmException, KeyManagementException {
//        CloseableHttpClient httpClient = HttpClientUtils.getClient();
        CloseableHttpResponse execute = null;
        try {
            System.out.println(uri);
            HttpPost httpPost = new HttpPost(uri);
            httpPost.setEntity(new StringEntity(data, "UTF-8"));
            httpPost.addHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType());
            httpPost.addHeader("Authorization", auth);
            execute = httpClient.execute(httpPost);
            return execute.getStatusLine().getStatusCode();
        } catch (IOException e) {
            return execute != null ? execute.getStatusLine().getStatusCode() : 0;
        } finally {
            if (execute != null) {
                try {
                    execute.close();
                } catch (IOException ignored) {
                }
            }
        }
    }
}
